"""
单元测试
"""

import pytest
from mongomock.database import Database
from mongomock.mongo_client import MongoClient
from starlette.testclient import TestClient

from main import app
from service import *

__all__ = [
    "Database",
    "TestClient",
    "TestCollection",
    "TestUser",
    "TestUrl",
    "app",
    "auth_client",
    "no_auth_client",
    "mock_db",
    "pytest",
    "fill_normal_user_auth",
]


class TestUser:
    """ 测试 | 用户信息 """

    class Normal:
        """ 测试 | 普通用户 """

        username: str = "normal_username"
        password: str = "normal_password"
        nickname: str = "normal_nickname"

    class Admin:
        """ 测试 | 管理员用户 """

        username: str = "admin_username"
        password: str = "admin_password"
        nickname: str = "admin_nickname"


class TestUrl:
    """ 测试 | URL """

    class User:
        """ 测试 | 用户模块 URL """

        USER_CHECK: str = "/api/v1/user/user/check/"
        """ 用户检查 """

        USER_LOGIN: str = "/api/v1/user/user/login/"
        """ 用户登录 """

        USER_REGISTER: str = "/api/v1/user/user/register/"
        """ 用户注册 """


class TestCollection:
    """ 测试 | 数据库集合 """

    class Admin:
        """ 测试 | 管理员集合 """

        API_ROUTE: str = APIRouteService.collection_name
        """ 接口路由 """

        REQUEST_LOG: str = RequestLogService.collection_name
        """ 请求日志 """

    class Common:
        """ 测试 | 通用集合 """

        PROCESS: str = ProcessService.collection_name
        """ 进度 """

        FILE: str = FileService.collection_name
        """ 文件 """

        FILE_GRID: str = f"{FileService.collection_name}.files"
        """ 文件 GridFS """

    class User:
        """ 测试 | 用户集合 """

        USER: str = UserService.collection_name
        """ 用户 """

        TOKEN: str = UserTokenService.collection_name
        """ 用户 Token """


@pytest.fixture
def mock_db() -> Database:
    """ 使用 mongomock 创建一个模拟的 MongoDB 连接 """

    return MongoClient()["test_ex"]


def fill_normal_user_auth(client: TestClient) -> None:
    """ 填充 auth 参数（普通用户） """

    user_register_json: dict = {
        "username": TestUser.Normal.username,
        "password": TestUser.Normal.password,
        "confirm_password": TestUser.Normal.password,
        "nickname": TestUser.Normal.nickname,
    }
    response = client.post(  # noqa
        url=TestUrl.User.USER_REGISTER,
        json=user_register_json,
    )


@pytest.fixture
def no_auth_client() -> TestClient:
    """ 客户端 | 未登录用户 """

    with TestClient(app) as client:
        return client


@pytest.fixture
def auth_client() -> TestClient:
    """ 客户端 | 普通用户 """

    user_register_json: dict = {
        "username": TestUser.Normal.username,
        "password": TestUser.Normal.password,
        "confirm_password": TestUser.Normal.password,
        "nickname": TestUser.Normal.nickname,
    }

    with TestClient(app) as client:
        response = client.post(
            url=TestUrl.User.USER_REGISTER,
            json=user_register_json,
        )
        token: str = (response.json().get("data") or {}).get("token") or ""
        assert response.status_code == 200
        assert bool(token), "Token 获取失败"
        client.headers = {
            "Authorization": f"EX {token}"
        }

    return client
